﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using TTMain.UI;
using Thurn_und_Taxis.components;

namespace Thurn_und_Taxis
{
    /// <summary>
    /// Interaction logic for ServerForm.xaml
    /// </summary>
    public partial class ServerForm : Window
    {
        private static Int32 DEFAULT_WIDTH = 1280;
        private static Int32 DEFAULT_HEIGHT = 1024;
        private static Int32 DEFAULT_HEIGHT_IMAGE = 134;
        

        private static Int32 DEFAULT_SERVER_CMP_HEIGHT = 650;
        private static Int32 DEFAULT_SERVER_CMP_WIDTH = 1000;

        private GameUI _gameUI;
        public delegate void UpdateInterfaceCallback();
        private Int16 _gameState;

        private const Int16 STATE_CONNECTING = 0;
        private const Int16 STATE_RETRY_CONNECTING = 1;
        private const Int16 STATE_ROOMS = 2;
        private const Int16 STATE_CREATE_TABLE = 3;
        private const Int16 STATE_JOIN_TABLE = 4;
        private const Int16 STATE_CONNECT_REFUSED = 5;

        public ServerForm(GameUI gameUI)
        {
            InitializeComponent();
            Double ratioHeight = System.Windows.SystemParameters.PrimaryScreenHeight / DEFAULT_HEIGHT;
            Double ratioWidth = System.Windows.SystemParameters.PrimaryScreenWidth / DEFAULT_WIDTH;
            ResizeVisualComponents(ratioHeight, ratioWidth);

            if (gameUI != null)
            {
                _gameUI = gameUI;

                _gameUI.RoomUpdated += new RoomUpdatedHandler(_gameUI_RoomUpdated);
                _gameUI.RefusedConnection += new RefusedConnectionHandler(_gameUI_RefusedConnection);
                _gameUI.CreatedRoomNAck += new CreatedRoomNAckHandler(_gameUI_CreatedRoomNAck);                
                _gameUI.PlayersList += new PlayersListHandler(_gameUI_PlayersList);

                _gameUI.ServerDownError += new ServerDownErrorHandler(_gameUI_ServerDownError);
                _gameUI.SocketError += new SocketErrorHandler(_gameUI_SocketError);
                _gameUI.Disconnect += new DisconnectHandler(_gameUI_Disconnect);
                
                cmpServerBox.CreateRoomRequest += new CreateRoomRequestHandler(cmpServerBox_CreateRoomRequest);
                cmpServerBox.JoinRoomRequest += new JoinRoomRequestHandler(cmpServerBox_JoinRoomRequest);

                labelConnecting.Content = _gameUI.GetGameSettings().Nickname + " is connecting to server ...";

                _gameUI.OpenLocalConnection();
                _gameState = STATE_CONNECTING;

                Thread threadConnect = new Thread(new ThreadStart(_gameUI.ConnectToServer));
                threadConnect.Start();
            }
        }

        void _gameUI_Disconnect(object sender)
        {
            try
            {
                canvasConnecting.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {
                        labelConnecting.Content = "The server has shut down. Please try again later";
                        canvasConnecting.Visibility = Visibility.Visible;
                        cmpServerBox.Visibility = Visibility.Collapsed;
                        buttonCancelConnecting.Content = "Back";
                        _gameState = STATE_CONNECT_REFUSED;
                    }
                );
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        void _gameUI_SocketError(object sender)
        {
            try
            {
                this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {
                        buttonCancelConnecting.Content = "Back";
                        labelConnecting.Content = "Error opening local socket. Make sure you firewall is not blocking the game";
                        _gameState = STATE_CONNECT_REFUSED;
                    }
                );
            }
            catch (Exception err)
            {

            }
        }

        void _gameUI_ServerDownError(object sender)
        {
            try
            {
                this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {
                        buttonCancelConnecting.Content = "Retry";
                        labelConnecting.Content = "Error connecting to server. The server might be down. Try again later";
                        _gameState = STATE_RETRY_CONNECTING;
                    }
                );
            }
            catch (Exception err)
            {

            }
        }

        void _gameUI_PlayersList(object sender, List<string> e)
        {
            try
            {
                canvasConnecting.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {   
                        cmpServerBox.UpdatePlayers(e);                        
                    }
                );
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        void _gameUI_CreatedRoomNAck(object sender)
        {
            try
            {
                cmpServerBox.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {
                        cmpServerBox.ShowErrorCode();
                    }
                );
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        void _gameUI_RefusedConnection(object sender)
        {
            try
            {
                canvasConnecting.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {
                        labelConnecting.Content = "Nickname already in use. Change nickname and try again";
                        buttonCancelConnecting.Content = "Back";
                        _gameState = STATE_CONNECT_REFUSED;
                    }
                );
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        void _gameUI_RoomUpdated(object sender, TTData.TTEventArgs.RoomUpdatesEventArgs e)
        {

            try
            {

                canvasConnecting.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateInterfaceCallback)delegate()
                    {
                        if (canvasConnecting.Visibility == Visibility.Visible)
                        {
                            canvasConnecting.Visibility = Visibility.Collapsed;
                            cmpServerBox.Visibility = Visibility.Visible;
                        }
                        cmpServerBox.UpdateRooms(e.RoomList);
                        _gameState = STATE_ROOMS;
                    }
                );
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }

        }

        void cmpServerBox_JoinRoomRequest(object sender, int roomId)
        {
            if (_gameUI != null)
            {
                _gameState = STATE_JOIN_TABLE;
                _gameUI.JoinRoom(roomId);
            }
        }

        void cmpServerBox_CreateRoomRequest(object sender, string roomName)
        {
            if (_gameUI != null)
            {
                _gameState = STATE_CREATE_TABLE;
                _gameUI.CreateNewGameRoom(roomName);
            }

        }

        private void buttonCancelConnecting_Click(object sender, RoutedEventArgs e)
        {
            switch (_gameState)
            {
                case STATE_RETRY_CONNECTING:
                    _gameUI.ConnectToServer();
                    break;
                case STATE_CONNECT_REFUSED:
                    this.Close();
                    break;
                case STATE_CONNECTING:
                    this.Close();
                    break;
            }            
        }

        private void ResizeVisualComponents(Double ratioHeight, Double ratioWidth)
        {
            cmpServerBox.Height = DEFAULT_SERVER_CMP_HEIGHT * ratioHeight;
            cmpServerBox.Width = DEFAULT_SERVER_CMP_WIDTH * ratioWidth;
            image_LeftDown.Height = DEFAULT_HEIGHT_IMAGE * ratioHeight;
            image_RightDown.Height = DEFAULT_HEIGHT_IMAGE * ratioHeight;
            image_RightUp.Height = DEFAULT_HEIGHT_IMAGE * ratioHeight;
            image_LeftUp.Height = DEFAULT_HEIGHT_IMAGE * ratioHeight;

            wrapMaskBottom.Height = 118 * ratioHeight;
            wrapMaskTop.Height = 118 * ratioHeight;
        }
    }
}
